#include "hr_tm.h"

uint32_t       g_e53_queue;
uint32_t       g_tcp_queue;
uint32_t       g_netrev_queue;
uint32_t       g_wifi_queue;
uint32_t       g_lcd_queue;

static int switch_task_process(task_type_e ty);

const char task_str[E_TASK_TYPE_MAX][32] = {
    [E_TASK_TYPE_HRD]         = "心率血氧任务",
    [E_TASK_TYPE_TM]          = "红外测温任务",
    [E_TASK_TYPE_ME]          = "心电图任务",
};

static hr_tm_t m_hr_tm = {
    .task_type = E_TASK_TYPE_HRD,
    .key = {
        .gpio = GPIO0_PA2,
        .func = MUX_GPIO,
        .type = PULL_UP,
        .drv = DRIVE_LEVEL7,
        .dir = LZGPIO_DIR_IN,
        .val = LZGPIO_LEVEL_KEEP,
    },
    .swtmr =
    {
        .cnt                    = 0,
        .args                   = &m_hr_tm,
        
        .getid_fn               = swtmr_getid,
        .start_fn               = swtmr_start,
        .stop_fn                = swtmr_stop,
        .init_fn                = swtmr_init,
    },
    
    .me.hrd_data  = {1, 2, 3, 4, 5},
};

static void wait_wdt_reboot(void)
{
    int wdt_type = 0; //立刻复位
    
    HAL_WDT_Init(HAL_CRU_ClkGetFreq(PCLK_MCU_BUS), WDT0);
    RequestIrq(WDT0_IRQn, NULL, WDT0);
    
    HAL_CRU_WdtGlbRstEnable(wdt_type);
    HAL_WDT_SetTimeout(1);
    printf(LOG_HRTM_TAG_INFO"reboot..........\r\n", __LINE__);
    LOS_Msleep(10);
    
    HAL_WDT_Start(wdt_type);
    LOS_IntLock();
    
    while (1) {
        LOS_Msleep(10);
    }
}

// 消息发送到网络
static void smart_medical_msg_send_to_net(void *msg, uint16_t cmd)
{
    dev_msg_t *dev = (dev_msg_t*)msg;
    
    memcpy(dev->head.num, m_hr_tm.devnum, sizeof(uint8_devnum));
    dev->head.type = Swap16(E_DEV_SMART_MEDICAL);
    dev->smart_medical.head.cmd_type = Swap16(cmd);
    
    if (0 != LOS_QueueWriteCopy(g_tcp_queue, &dev->smart_medical, sizeof(msg_smart_medical_t), QUEUE_DEFAULT_WRITE_TIME_MS)) {
        WRITE_QUEUE_ERR_LOG(g_tcp_queue);
    }
}

// 查找设备响应
static void smart_medical_msg_send_to_net_search_dev(uint8_t response)
{
    dev_msg_t dev = {0};
    dev.smart_medical.search_dev.response = response;
    smart_medical_msg_send_to_net(&dev, E_SMART_MEDICAL_CMD_SEARCH_DEV);
}

// hrd状态上报
static void smart_medical_msg_send_to_net_report_hrd(uint8_t response,
                                                     uint8_t hrd_v,
                                                     uint8_t hrd,
                                                     uint8_t spo_v,
                                                     uint8_t spo)
{
    dev_msg_t dev = {0};
    
    dev.smart_medical.head.response            = response;
    dev.smart_medical.report_hrd.hrd_v         = hrd_v;
    dev.smart_medical.report_hrd.hrd           = hrd;
    dev.smart_medical.report_hrd.spo_v         = spo_v;
    dev.smart_medical.report_hrd.spo           = spo;
    smart_medical_msg_send_to_net(&dev, E_SMART_MEDICAL_CMD_REPORT_HRD);
}

// tm状态上报
static void smart_medical_msg_send_to_net_report_tm(uint8_t  response,
                                                    uint8_t  tm_v,
                                                    uint16_t tm)
{
    dev_msg_t dev = {0};
    
    dev.smart_medical.head.response           = response;
    dev.smart_medical.report_tm.tm_v          = tm_v;
    dev.smart_medical.report_tm.tm            = Swap16(tm);
    smart_medical_msg_send_to_net(&dev, E_SMART_MEDICAL_CMD_REPORT_TM);
}

// me状态上报
static void smart_medical_msg_send_to_net_report_me(uint8_t  response,
                                                    uint8_t  hrd,
                                                    uint32_t frame_num,
                                                    uint32_t *me)
{
    dev_msg_t dev = {0};
    
    dev.smart_medical.head.response           = response;
    dev.smart_medical.report_me.hrd           = hrd;
    dev.smart_medical.report_me.frame_num     = frame_num;
    memcpy(dev.smart_medical.report_me.hrd_data, me, sizeof(uint32_hrd));
    smart_medical_msg_send_to_net(&dev, E_SMART_MEDICAL_CMD_REPORT_ME);
}

// 解析并发送设备响应
static void net_data_response(dev_msg_t dev)
{
    hr_tm_t  *hr_tm = (hr_tm_t*)&m_hr_tm;
    
    if (dev.smart_medical.head.cmd_type != E_SMART_MEDICAL_CMD_SEARCH_DEV
            && memcmp(dev.head.num, hr_tm->devnum, DEVNUM_LEN) != 0
            && memcmp(dev.head.num, COMMON_DEV, DEVNUM_LEN) != 0) {
        uint8_t *devnum = dev.head.num;
        printf(LOG_HRTM_TAG_NET_DATA"other dev msg:%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x=============\n\n", __LINE__,
               devnum[0], devnum[1], devnum[2], devnum[3], devnum[4],  devnum[5],
               devnum[6], devnum[7], devnum[8], devnum[9], devnum[10], devnum[11]
              );
        return;
    }
    
    if (dev.head.type != E_DEV_SMART_MEDICAL && dev.smart_medical.head.cmd_type != E_SMART_MEDICAL_CMD_RESET) {
        printf(LOG_HRTM_TAG_NET_DATA"dev type different:%04x=============\n\n", __LINE__, dev.head.type);
        return;
    }
    
    switch (dev.smart_medical.head.cmd_type) {
        case E_SMART_MEDICAL_CMD_SEARCH_DEV:
            printf(LOG_HRTM_TAG_NET_DATA"search dev response\n", __LINE__);
            smart_medical_msg_send_to_net_search_dev(SMART_MEDICAL_RESPONSE_SUCCESS);
            break;
            
        case E_SMART_MEDICAL_CMD_REPORT_HRD:
            printf(LOG_HRTM_TAG_NET_DATA"report hrd\n", __LINE__);
            smart_medical_msg_send_to_net_report_hrd(SMART_MEDICAL_RESPONSE_SUCCESS,
                                                     hr_tm->hrd.hrd_v, hr_tm->hrd.hrd, hr_tm->hrd.spo_v, hr_tm->hrd.spo);
            break;
            
        case E_SMART_MEDICAL_CMD_REPORT_TM:
            printf(LOG_HRTM_TAG_NET_DATA"report tm\n", __LINE__);
            smart_medical_msg_send_to_net_report_tm(SMART_MEDICAL_RESPONSE_SUCCESS,
                                                    hr_tm->tm.tm_v, hr_tm->tm.tm);
            break;
            
        case E_SMART_MEDICAL_CMD_REPORT_ME:
            if (dev.smart_medical.head.response == SMART_MEDICAL_RESPONSE_FAILURE) {
                printf(LOG_HRTM_TAG_NET_DATA"report me\n", __LINE__);
                smart_medical_msg_send_to_net_report_me(SMART_MEDICAL_RESPONSE_SUCCESS, hr_tm->me.hrd, hr_tm->me.frame_num, hr_tm->me.hrd_data);
            } else if (dev.smart_medical.report_me.frame_num == m_hr_tm.me.frame_num) {
                //停止重发定时器
                // printf(LOG_HRTM_TAG_NET_DATA"me response\n", __LINE__);
                hr_tm->swtmr.stop_fn(&hr_tm->swtmr, STR_SH_SWTMR_ME_RETRY_SEND);
            }
            break;
            
        case E_SMART_MEDICAL_CMD_SET_TASK:
            if (dev.smart_medical.set_task.id > 0 && dev.smart_medical.set_task.id <= E_TASK_TYPE_MAX) {
                printf(LOG_HRTM_TAG_NET_DATA"set run task id:%d (%s)\n", __LINE__, dev.smart_medical.set_task.id, task_str[dev.smart_medical.set_task.id - 1]);
                if (hr_tm->task_type != dev.smart_medical.set_task.id - 1) {
                    LOS_Msleep(500);
                    if (switch_task_process(dev.smart_medical.set_task.id - 1) >= 0) {
                        hr_tm->task_type = dev.smart_medical.set_task.id - 1;
                        dev.smart_medical.head.response = SMART_MEDICAL_RESPONSE_SUCCESS;
                    } else {
                        dev.smart_medical.head.response = SMART_MEDICAL_RESPONSE_FAILURE;
                    }
                    LOS_Msleep(1000);
                }
                smart_medical_msg_send_to_net(&dev, E_SMART_MEDICAL_CMD_SET_TASK);
            } else {
                printf(LOG_HRTM_TAG_NET_DATA"set run task err:%d!!!\n", __LINE__, dev.smart_medical.set_task.id);
                dev.smart_medical.head.response = SMART_MEDICAL_RESPONSE_FAILURE;
                smart_medical_msg_send_to_net(&dev, E_SMART_MEDICAL_CMD_SET_TASK);
            }
            break;
            
        case E_SMART_MEDICAL_CMD_RESET:
            dev.smart_medical.search_dev.response = SMART_MEDICAL_RESPONSE_SUCCESS;
            smart_medical_msg_send_to_net(&dev, E_SMART_MEDICAL_CMD_RESET);
            LOS_Msleep(500);
            printf(LOG_HRTM_TAG_NET_DATA"reset smart medical\n", __LINE__);
            wait_wdt_reboot();
            break;
            
        default:
            printf(LOG_HRTM_TAG_NET_DATA"cmd no such type:%04x=============\n\n", __LINE__, dev.smart_medical.head.cmd_type);
            break;
    }
}

static void key_init(void)
{
    if (PinctrlInit(m_hr_tm.key) != 0) {
        printf(LOG_HRTM_TAG_INFO"pin %d init failed\n", __LINE__, m_hr_tm.key.gpio);
    }
}

static key_type_e key_scan(void)
{
    LzGpioValue v  = LZGPIO_LEVEL_HIGH;
    
    LzGpioGetVal(m_hr_tm.key.gpio, &v);
    
    if (v != LZGPIO_LEVEL_HIGH) {
        LOS_Msleep(10);
        LzGpioGetVal(m_hr_tm.key.gpio, &v);
        if (v != LZGPIO_LEVEL_HIGH) {
            return E_KEY_TYPE_DOWN;
        }
    }
    
    return E_KEY_TYPE_NO;
}

void delete_last_task(task_args_t *task, task_type_e tyl)
{
    if (tyl < E_TASK_TYPE_MAX) {
        if (task[tyl].state != 0) {
            printf(LOG_HRTM_TAG_INFO"delete last task:%d waiting ...\r\n", __LINE__, tyl);
            if (tyl == E_TASK_TYPE_ME) {
                e53_em_thread_delete();
            } else if (tyl == E_TASK_TYPE_HRD) {
                Max30102_Reset();
            }
            LOS_TaskDelete(task[tyl].id);
        }
        task[tyl].state = 0;
    }
}

static int switch_task_process(task_type_e ty)
{
    static task_type_e tyl = E_TASK_TYPE_MAX;
    static task_args_t task[E_TASK_TYPE_MAX] = {0};
    
    if (tyl != ty && ty < E_TASK_TYPE_MAX) {
        if (m_hr_tm.switch_task_time != 0 && get_time_us(m_hr_tm.switch_task_time) < 5000000) {
            return -1;
        }
        
        m_hr_tm.swtmr.stop_fn(&m_hr_tm.swtmr, STR_SH_SWTMR_ME_RETRY_SEND);
        delete_last_task(task, tyl);
        tyl = ty;
        
        switch (tyl) {
            case E_TASK_TYPE_HRD:
            
                create_task(&task[tyl].id, 10240, 2, e53_hrd_thread, NULL, "e53_hrd_thread");
                task[tyl].state = 1;
                break;
            case E_TASK_TYPE_TM:
            
                create_task(&task[tyl].id, 10240, 2, e53_tm_thread, NULL, "e53_tm_thread");
                task[tyl].state = 1;
                break;
            case E_TASK_TYPE_ME:
            
                create_task(&task[tyl].id, 10240, 2, e53_em_thread, NULL, "e53_em_thread");
                task[tyl].state = 1;
                break;
            default:
                break;
        }
        m_hr_tm.switch_task_time = get_current_tick();
        return 0;
    }
    return 1;
}


void test_send_e53_data(void)
{
    uint8_t *data;
    static int cnt  = 0, num = 0;
    
    
    if (++cnt >= E_TASK_TYPE_MAX) {
        cnt = 0;
    }
    ++num;
    msg_smart_medical_report_hrd_t hrd = {0};
    msg_smart_medical_report_tm_t  tm  = {0};
    msg_smart_medical_report_me_t  me  = {0};
    
    switch (cnt) {
        case E_TASK_TYPE_HRD: {
            hrd.hrd_v = 1;
            hrd.hrd   = num % 80;
            hrd.spo_v = 1;
            hrd.spo   = num % 100;
            data      = (uint8_t *)&hrd;
            break;
        }
        case E_TASK_TYPE_TM: {
            tm.tm_v = 2;
            tm.tm   = num % 38;
            data    = (uint8_t *)&tm;
            break;
        }
        case E_TASK_TYPE_ME: {
            me.hrd           = num % 80;
            me.hrd_data[0]   = 0x12345678;
            me.hrd_data[1]   = 0xab01cdef;
            me.hrd_data[318] = 0x12345678;
            me.hrd_data[319] = 0xab01cdef;
            data       = (uint8_t *)&me;
            break;
        }
        default:
            return;
    }
    send_e53_data(cnt, data);
}


// 定时上报数据
void report_state_time_handle(UINT32 para)
{
    hr_tm_t  *hr_tm = (hr_tm_t*)para;
    
    if (hr_tm->report_flag) {
        // if(hr_tm->task_type != E_TASK_TYPE_ME) printf(LOG_HRTM_TAG_SWTMR"%s report %s\n", __LINE__, task_str[hr_tm->task_type], hr_tm->report_flag?" ":"waiting");
        
        switch (hr_tm->task_type) {
            case E_TASK_TYPE_HRD:
                smart_medical_msg_send_to_net_report_hrd(SMART_MEDICAL_RESPONSE_SUCCESS,
                                                         m_hr_tm.hrd.hrd_v, m_hr_tm.hrd.hrd, m_hr_tm.hrd.spo_v, m_hr_tm.hrd.spo);
                break;
                
            case E_TASK_TYPE_TM:
                smart_medical_msg_send_to_net_report_tm(SMART_MEDICAL_RESPONSE_SUCCESS,
                                                        m_hr_tm.tm.tm_v, m_hr_tm.tm.tm);
                break;
                
            case E_TASK_TYPE_ME:
                // smart_medical_msg_send_to_net_report_me(SMART_MEDICAL_RESPONSE_SUCCESS, hr_tm->me.hrd, hr_tm->me.frame_num,  hr_tm->me.hrd_data);
                break;
                
            default:
                break;
        }
    }
}

// 超时重发me数据
void me_retry_send_time_handle(UINT32 para)
{
    hr_tm_t  *hr_tm = (hr_tm_t*)para;
    
    if (hr_tm->task_type == E_TASK_TYPE_ME && hr_tm->report_flag) {
        printf(LOG_HRTM_TAG_SWTMR"%s report %s\n", __LINE__, task_str[hr_tm->task_type], hr_tm->report_flag ? " " : "waiting");
        smart_medical_msg_send_to_net_report_me(SMART_MEDICAL_RESPONSE_SUCCESS, hr_tm->me.hrd, hr_tm->me.frame_num,  hr_tm->me.hrd_data);
    }
}

// 发送e53数据
void send_e53_data(int task_type, void *data)
{
    dev_msg_t dev   = {0};
    
    if (task_type != m_hr_tm.task_type) {
        return;
    }
    
    switch (task_type) {
        case E_TASK_TYPE_HRD: {
            msg_smart_medical_report_hrd_t *hrd = (msg_smart_medical_report_hrd_t*)data;
            dev.smart_medical.report_hrd    = *hrd;
            dev.smart_medical.head.cmd_type = (E_SMART_MEDICAL_CMD_REPORT_HRD);
        }
        break;
        
        case E_TASK_TYPE_TM: {
            msg_smart_medical_report_tm_t *tm = (msg_smart_medical_report_tm_t*)data;
            dev.smart_medical.report_tm     = *tm;
            dev.smart_medical.report_tm.tm  = tm->tm;
            dev.smart_medical.head.cmd_type = (E_SMART_MEDICAL_CMD_REPORT_TM);
        }
        break;
        
        case E_TASK_TYPE_ME: {
            msg_smart_medical_report_me_t *me = (msg_smart_medical_report_me_t*)data;
            dev.smart_medical.report_me     = *me;
            dev.smart_medical.head.cmd_type = (E_SMART_MEDICAL_CMD_REPORT_ME);
        }
        break;
        
        default:
            return;
    }
    
    memcpy(dev.head.num, m_hr_tm.devnum, sizeof(uint8_devnum));
    dev.head.type = E_DEV_SMART_MEDICAL;
    // printf("\n"LOG_HRTM_TAG_E53_DATA"send dev_type:%04x, cmd_type:%04x\n\n", __LINE__, dev.head.type, dev.smart_medical.head.cmd_type);
    if (0 != LOS_QueueWriteCopy(g_e53_queue, &dev, sizeof(dev_msg_t), QUEUE_DEFAULT_WRITE_TIME_MS)) {
        WRITE_QUEUE_ERR_LOG(g_e53_queue);
    }
}

// 更新53数据
static void update_e53_data(hr_tm_t *hr_tm, dev_msg_t *dev)
{
    switch (dev->smart_medical.head.cmd_type) {
        case E_SMART_MEDICAL_CMD_REPORT_HRD:
            if (hr_tm->task_type == E_TASK_TYPE_HRD) {
                hr_tm->hrd.hrd_v   = dev->smart_medical.report_hrd.hrd_v;
                hr_tm->hrd.hrd     = dev->smart_medical.report_hrd.hrd;
                hr_tm->hrd.spo_v   = dev->smart_medical.report_hrd.spo_v;
                hr_tm->hrd.spo     = dev->smart_medical.report_hrd.spo;
            }
            break;
            
        case E_SMART_MEDICAL_CMD_REPORT_TM:
            if (hr_tm->task_type == E_TASK_TYPE_TM) {
                hr_tm->tm.tm_v     = dev->smart_medical.report_tm.tm_v;
                hr_tm->tm.tm       = dev->smart_medical.report_tm.tm;
            }
            break;
            
        case E_SMART_MEDICAL_CMD_REPORT_ME:
            if (hr_tm->task_type == E_TASK_TYPE_ME) {
                // printf(LOG_HRTM_TAG_E53_DATA"frame:%d\n\n", __LINE__, hr_tm->me.frame_num);
                
                hr_tm->swtmr.stop_fn(&hr_tm->swtmr, STR_SH_SWTMR_ME_RETRY_SEND);
                hr_tm->me.hrd = dev->smart_medical.report_me.hrd;
                hr_tm->me.frame_num++;
                memcpy(hr_tm->me.hrd_data, dev->smart_medical.report_me.hrd_data, sizeof(hr_tm->me.hrd_data));
                if (hr_tm->report_flag) {
                    smart_medical_msg_send_to_net_report_me(SMART_MEDICAL_RESPONSE_SUCCESS, hr_tm->me.hrd, hr_tm->me.frame_num,  hr_tm->me.hrd_data);
                    // hr_tm->swtmr.start_fn(&hr_tm->swtmr, STR_SH_SWTMR_ME_RETRY_SEND);   //重发定时器
                }
            }
            break;
            
        default:
            break;
    }
}


// 接收e53数据处理
void rev_e53_data_process(void *args)
{
    TASK_PROCESS_START_LOG();
    hr_tm_t   *hr_tm = &m_hr_tm;
    
    while (1) {
        app_msg_data_t m   = {0};
        uint32_t       len = sizeof(app_msg_data_t);
        
        if (LOS_QueueReadCopy(g_e53_queue, &m, &len, LOS_WAIT_FOREVER) != LOS_OK) {
            continue;
        }
        // printf("\n"LOG_HRTM_TAG_E53_DATA"rev  dev_type:%04x, cmd_type:%04x\n\n", __LINE__, m.dev_msg.head.type, m.dev_msg.smart_medical.head.cmd_type);
        update_e53_data(hr_tm, &m.dev_msg);
    }
}

// 接收网络数据处理
void rev_net_data_process(void *args)
{
    TASK_PROCESS_START_LOG();
    LOS_Msleep(6);
    
    while (1) {
        app_msg_data_t m   = {0};
        uint32_t       len = sizeof(app_msg_data_t);
        
        if (LOS_QueueReadCopy(g_netrev_queue, &m, &len, LOS_WAIT_FOREVER) != LOS_OK) {
            continue;
        }
        printf(LOG_HRTM_TAG_NET_DATA"len:%d, dev_type:%04x, cmd_type:%04x\n", __LINE__, len, m.dev_msg.head.type, m.dev_msg.smart_medical.head.cmd_type);
        net_data_response(m.dev_msg);
    }
}

void e53_hrtm_thread(void *args)
{
    TASK_PROCESS_START_LOG();
    hr_tm_t *hr_tm = &m_hr_tm;
    
    key_init();
    key_type_e  key       = E_KEY_TYPE_MAX;
    key_type_e  keylast   = E_KEY_TYPE_MAX;
    
    lcd_io_init();
    
    if (lcd_init(2) != 0) {
        printf("lcd_init failed\n");
        return;
    }
    
    switch_task_process(hr_tm->task_type);
    
    hr_tm->swtmr.init_fn(TIM_REPORT_STATE_MS,  report_state_time_handle,  STR_SH_SWTMR_REPORT_STATE,  (uint32_t *)&hr_tm->swtmr);
    hr_tm->swtmr.init_fn(TIM_ME_RETRY_SEND_MS, me_retry_send_time_handle, STR_SH_SWTMR_ME_RETRY_SEND, (uint32_t *)&hr_tm->swtmr);
    hr_tm->swtmr.start_fn(&hr_tm->swtmr, STR_SH_SWTMR_REPORT_STATE);
    
    while (1) {
        key = key_scan();
        if (key != keylast) {
            if (keylast == E_KEY_TYPE_DOWN) {
                task_type_e ty = hr_tm->task_type;
                ++ty;
                ty = ty % E_TASK_TYPE_MAX;
                
                if (switch_task_process(ty) >= 0) {
                    hr_tm->task_type = ty;
                }
                
                printf(LOG_HRTM_TAG_INFO"task_type:%d %s\r\n", __LINE__, hr_tm->task_type, task_str[hr_tm->task_type]);
            }
            keylast = key;
        }
        
        app_msg_t m       = {0};
        uint32_t  msglen  = sizeof(app_msg_t);
        if (LOS_QueueReadCopy(g_lcd_queue, &m, &msglen, 100) != LOS_OK) {
            continue;
        }
        if (m.cmd.msg_type != E_MSG_CMD
                || m.cmd.data_type != E_DATA_WIFI_LCD
                || (m.cmd.wifi_lcd.type != E_DATA_WIFI_SERVER_LINK && m.cmd.wifi_lcd.type != E_DATA_WIFI_SERVER_NOLINK)) {
            continue;
        }
        LOS_Msleep(50);
        hr_tm->report_flag = m.cmd.wifi_lcd.type == E_DATA_WIFI_SERVER_LINK ? 1 : 0;
        // printf(LOG_HRTM_TAG_INFO"UDP %s\r\n", __LINE__, m.cmd.wifi_lcd.type == E_DATA_WIFI_SERVER_LINK? "linked":"no link");
    }
}


void e53_hrtm_example()
{
    hr_tm_t *hr_tm = &m_hr_tm;
    
    get_rk2206_efuse(hr_tm->devnum);
    
    if (LOS_QueueCreate("queue", QUEUE_LEN_MAX, &g_e53_queue, 0, sizeof(app_msg_data_t))) {
        printf(LOG_HRTM_TAG_INFO"e53_queue Falied to create Message Queue!\n", __LINE__);
    } else {
        printf(LOG_HRTM_TAG_INFO"e53_queue to create Message Queue! count:%d, len:%d\n", __LINE__, QUEUE_LEN_MAX, sizeof(app_msg_data_t));
    }
    
    if (LOS_QueueCreate("queue", QUEUE_LEN_MAX, &g_tcp_queue, 0, sizeof(app_msg_data_t))) {
        printf(LOG_HRTM_TAG_INFO"tcp_queue Falied to create Message Queue!\n", __LINE__);
    } else {
        printf(LOG_HRTM_TAG_INFO"tcp_queue to create Message Queue! count:%d, len:%d\n", __LINE__, QUEUE_LEN_MAX, sizeof(app_msg_data_t));
    }
    
    if (LOS_QueueCreate("queue", QUEUE_LEN_MAX, &g_netrev_queue, 0, sizeof(app_msg_data_t))) {
        printf(LOG_HRTM_TAG_INFO"netrev_queue Falied to create Message Queue!\n", __LINE__);
    } else {
        printf(LOG_HRTM_TAG_INFO"netrev_queue to create Message Queue! count:%d, len:%d\n", __LINE__, QUEUE_LEN_MAX, sizeof(app_msg_data_t));
    }
    
    if (LOS_QueueCreate("queue", QUEUE_LEN_MAX, &g_wifi_queue, 0, sizeof(app_msg_t))) {
        printf(LOG_HRTM_TAG_INFO"wifi_queue Falied to create Message Queue!\n", __LINE__);
    } else {
        printf(LOG_HRTM_TAG_INFO"wifi_queue to create Message Queue! count:%d, len:%d\n", __LINE__, QUEUE_LEN_MAX, sizeof(app_msg_t));
    }
    
    if (LOS_QueueCreate("queue", QUEUE_LEN_MAX, &g_lcd_queue, 0, sizeof(app_msg_t))) {
        printf(LOG_HRTM_TAG_INFO"lcd_queue Falied to create Message Queue!\n", __LINE__);
    } else {
        printf(LOG_HRTM_TAG_INFO"lcd_queue to create Message Queue! count:%d, len:%d\n", __LINE__, QUEUE_LEN_MAX, sizeof(app_msg_t));
    }
    
    create_task(&hr_tm->thread_id[THREAD_ID_HR_TM],    20240, 17,   e53_hrtm_thread,           NULL, "hrtm process");
    create_task(&hr_tm->thread_id[THREAD_ID_WIFI],     20240, 17,   wifi_process,              NULL, "hrtm wifi");
    create_task(&hr_tm->thread_id[THREAD_ID_REV_NETD], 20240, 18,   rev_net_data_process,      NULL, "hrtm rev net data");
    create_task(&hr_tm->thread_id[THREAD_ID_REV_E53],  20240, 18,   rev_e53_data_process,      NULL, "hrtm rev e53 data");
}


APP_FEATURE_INIT(e53_hrtm_example);
